From 273ade90da6108435ba9827d88b3b2f245c98045 Mon Sep 17 00:00:00 2001 From: robertl Date: Sun, 23 Jul 2006 19:45:12 +0000 Subject: [PATCH] Correctly implement zero byte write after packet that's a multiple of frame size. --- jeeps/gpslibusb.c | 4 ++++ jeeps/gpsusbcommon.c | 12 ++++++++++++ jeeps/gpsusbcommon.h | 1 + jeeps/gpsusbwin.c | 10 ++-------- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/jeeps/gpslibusb.c b/jeeps/gpslibusb.c index dcaa8bd63..722635f21 100644 --- a/jeeps/gpslibusb.c +++ b/jeeps/gpslibusb.c @@ -54,6 +54,7 @@ typedef struct { static int gusb_intr_in_ep; static int gusb_bulk_out_ep; static int gusb_bulk_in_ep; +static gusb_llops_t libusb_llops; static usb_dev_handle *udev; static void garmin_usb_scan(libusb_unit_data *, int); @@ -71,6 +72,7 @@ gusb_libusb_send(const garmin_usb_packet *opkt, size_t sz) usb_strerror()); } } + return r; } @@ -214,10 +216,12 @@ garmin_usb_start(struct usb_device *dev) fatal("Claim interfaced failed: %s\n", usb_strerror()); } + libusb_llops.max_tx_size = dev->descriptor.bMaxPacketSize0; for (i = 0; i < dev->config->interface->altsetting->bNumEndpoints; i++) { struct usb_endpoint_descriptor * ep; ep = &dev->config->interface->altsetting->endpoint[i]; + switch (ep->bmAttributes & USB_ENDPOINT_TYPE_MASK) { #define EA(x) x & USB_ENDPOINT_ADDRESS_MASK case USB_ENDPOINT_TYPE_BULK: diff --git a/jeeps/gpsusbcommon.c b/jeeps/gpsusbcommon.c index a75e90f1b..35ac8d684 100644 --- a/jeeps/gpsusbcommon.c +++ b/jeeps/gpsusbcommon.c @@ -170,6 +170,18 @@ gusb_cmd_send(const garmin_usb_packet *opkt, size_t sz) GPS_Diag("(%-8s%s)\n", m1, m2 ? m2 : ""); } + /* + * Recursion, when used in a disciplined way, can be our friend. + * + * The Garmin protocol requires that packets that are exactly + * a multiple of the max tx size be followed by a zero length + * packet. Do that here so we can see it in debugging traces. + */ + + if (sz && !(sz % gusb_llops->max_tx_size)) { + gusb_cmd_send(opkt, 0); + } + return (rv); } diff --git a/jeeps/gpsusbcommon.h b/jeeps/gpsusbcommon.h index 677e75789..b0865f5f0 100644 --- a/jeeps/gpsusbcommon.h +++ b/jeeps/gpsusbcommon.h @@ -32,6 +32,7 @@ typedef struct gusb_llops { gusb_llop_get llop_get_bulk; gusb_llop_send llop_send; gusb_llop_close llop_close; + int max_tx_size; } gusb_llops_t; /* Provided by the common code. */ diff --git a/jeeps/gpsusbwin.c b/jeeps/gpsusbwin.c index 8e003ea44..d823738f0 100644 --- a/jeeps/gpsusbwin.c +++ b/jeeps/gpsusbwin.c @@ -72,7 +72,6 @@ gusb_win_get(garmin_usb_packet *ibuf, size_t sz) DWORD rxed = GARMIN_USB_INTERRUPT_DATA_SIZE; unsigned char *buf = (unsigned char *) &ibuf->dbuf; int tsz=0; - unsigned char *obuf = buf; while (sz) { /* The driver wrongly (IMO) rejects reads smaller than @@ -118,13 +117,7 @@ gusb_win_send(const garmin_usb_packet *opkt, size_t sz) WriteFile(usb_handle, obuf, sz, &rsz, NULL); if (rsz != sz) { - fatal ("Error sending %d bytes. Successfully sent %d\n", sz, rsz); - } - - if (0 == sz % usb_tx_packet_size) { - DWORD sz2; - GPS_Diag("Writing padding buffer.\n"); - WriteFile(usb_handle, 0, 0, &sz2, NULL); + fatal ("Error sending %d bytes. Successfully sent %ld\n", sz, rsz); } return rsz; @@ -177,6 +170,7 @@ HANDLE * garmin_usb_start(HDEVINFO* hdevinfo, SP_DEVICE_INTERFACE_DATA *infodata &size, NULL)) { fatal("Couldn't get USB packet size.\n"); } + win_llops.max_tx_size = usb_tx_packet_size; gusb_syncup(); -- 2.30.2